package com.comven.example.srouce.aspect;

import com.comven.example.srouce.annotation.DBName;
import com.comven.example.srouce.constant.DataSourceType;
import com.comven.example.srouce.util.DataSourceContextHodler;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @author: xiongxin
 * @create: 2022/9/23 17:03
 * @desc: 数据源切换实现
*/

@Aspect
@Component
//需要注意下该切面必须要在事务注解@Transactional之前，
//由于在开始事务之前就需要确定数据源，@Transactional的order是最小值
//设置DataSourceAspect的@Order(Ordered.LOWEST_PRECEDENCE-1)
//同属AOP 设置order进行指定加载顺序
//@Order(Ordered.LOWEST_PRECEDENCE-1)//数据源加载顺序
public class DataSourceAspect {
	@Before("@annotation(com.comven.example.srouce.annotation.DBName)")
	public void change(JoinPoint point) throws Throwable {
		try {
			MethodSignature signature = (MethodSignature)point.getSignature();
			//获取切换数据源类型
			DBName makeDataSourceType = signature.getMethod().getAnnotation(DBName.class);
			DataSourceType annotationType = makeDataSourceType.value();
			if(annotationType != null) {
				//根据类型进行调用填充数据源切换方法
				DataSourceContextHodler.setContextKey(annotationType.name());
			} else {
				DataSourceContextHodler.setContextKey(DataSourceType.base.name());
			}
		} catch(Exception e) {

			e.printStackTrace();
		}
	}
	@After("@annotation(com.comven.example.srouce.annotation.DBName)")
	public void afterClear(JoinPoint point) {
		//清空线程变量
		DataSourceContextHodler.clear();
	}
}